import path from 'path';
import { split_index, count_front } from '../config/dlt-config.mjs';
import FsDriver from './FsDriver.mjs';

const fsDriver = new FsDriver();
/**
 * 数据源模型类
 * @version 1.0.3
 */
class DltDataModel {

    /**
     * 缓存键名
     */
    cacheKeyOfDataSource = path.join(import.meta.dirname, '../data/dlt/data-all.json');
    cacheKeyOfRefreshTime = path.join(import.meta.dirname, '../data/dlt/refresh-time.txt');
    cacheKeyOfActiveDrawNum = path.join(import.meta.dirname, '../data/dlt/active-drawnum.txt');

    /**
     * 设置数据源
     * @param {Array} rows 
     */
    setDataSource(rows) {
        fsDriver.save(this.cacheKeyOfDataSource, JSON.stringify(rows));
        console.log('【DltDataSource数据库】setDataSource ', rows);
    }

    /**
     * 返回数据源
     * @param {String} activeDrawNum 本期期号
     * @param {Number} offset 偏移量，无需修改
     * @returns {Array} 示例：[{lotteryDrawNum: "25066", lotteryDrawResult: "15 18 27 28 34 03 06", lotteryDrawTime: "2025-06-14"}, ...]
     */
    getDataSource(activeDrawNum = '', offset = 1) {
        let dataset = JSON.parse(fsDriver.get(this.cacheKeyOfDataSource) ?? '[]');
        if (activeDrawNum) {
            let pos = dataset.findIndex(v => v.lotteryDrawNum == activeDrawNum);
            if (pos > -1) {
                return dataset.slice(pos + offset);
            }
        }
        return dataset;
    }

    getLastRecord() {
        let dataset = this.getDataSource();
        return dataset.length > 0 ? dataset[dataset.length - 1] : {};
    }

    /**
     * 设置时光机期号
     * @param {Number} num 
     */
    setActiveDrawNum(num) {
        fsDriver.save(this.cacheKeyOfActiveDrawNum, num);
    }

    /**
     * 获取时光机期号
     * @returns {String} 返回期号
     */
    getActiveDrawNum() {
        return fsDriver.get(this.cacheKeyOfActiveDrawNum) || '';
    }

    /**
     * 设置刷新时间
     */
    setRefreshTime() {
        let refreshTime = new Date().getTime();
        fsDriver.save(this.cacheKeyOfRefreshTime, refreshTime);
    }

    getRefreshTime(isLocalString = false) {
        let refreshTime = parseInt(fsDriver.get(this.cacheKeyOfRefreshTime) ?? '0');
        console.log('refreshTime', refreshTime);
        if (isLocalString && refreshTime > 0) {
            // 返回本地存储的时间字符串
            let date = new Date(refreshTime);
            let info = {
                Y: date.getFullYear(),
                m: ('0' + (date.getMonth() + 1)).slice(-2),
                d: ('0' + date.getDate()).slice(-2),
                H: ('0' + date.getHours()).slice(-2),
                i: ('0' + date.getMinutes()).slice(-2),
                s: ('0' + date.getSeconds()).slice(-2),
                w: date.getDay(),
                ww: ['日', '一', '二', '三', '四', '五', '六'][date.getDay()],
            }
            return `${info.Y}-${info.m}-${info.d} 周${info.ww} ${info.H}:${info.i}:${info.s}`;
        }
        return refreshTime;
    }

    /**
     * 检测刷新时间是否过期
     * @param {Number} time 秒
     * @returns Boolean 如果超过指定时间，则返回 true，表示需要刷新数据
     */
    isExpire(time = 7200) {
        return (new Date().getTime() - this.getRefreshTime(false)) > (time * 1000);
    }

    /**
     * 返回指定号数的列数据
     * @param {Array} data 数据
     * @param {Number} columnIdx 号数列索引（从 0 到 6）
     * @param {Boolean} isLocation 是否是位置数据
     * @returns {Array}
     */
    getColumnData(data, columnIdx, isLocation = false) {
        // const data = getDataSource();
        if (isLocation) {
            let inc = columnIdx < split_index ? 0 : count_front;
            // 返回位置数据，前 5 列是红球，后 2 列是蓝球
            return data.map((row, i) => {
                return [i, parseInt(row.lotteryDrawResult.split(' ')[columnIdx]) + inc];
            });
        }
        return data.map(row => row.lotteryDrawResult.split(' ')[columnIdx]);
    }

    /**
     * 获取每个号码的出现次数统计。包含全部号码（前后区）统计和每个号数列（1-7）的统计
     * @param {Array} dataset 数据源，默认为当前数据源
     * @returns Object {statAll, statColumns}
     */
    getDrawalStat(dataset) {
        if (!dataset) {
            dataset = this.getDataSource();
        }
        let statColumns = [{}, {}, {}, {}, {}, {}, {}]; // 1...7
        let statAll = [{}, {}]; // front/back
        let pos = 0; // 是否是前区号码
        dataset.forEach(row => {
            row.lotteryDrawResult.split(' ').forEach((num, i) => {
                pos = i < split_index ? 0 : 1;
                statAll[pos][num] = statAll[pos][num] ? statAll[pos][num] + 1 : 1;
                statColumns[i][num] = statColumns[i][num] ? statColumns[i][num] + 1 : 1;
            });
        });
        dataset = null;
        // 排序
        let statAllSorted = [{}, {}];
        for (let i = 0; i < 2; i++) {
            Object.keys(statAll[i]).sort().forEach(key => {
                statAllSorted[i]['N' + key] = statAll[i][key];
            });
        }
        statAll = null;
        let statColumnsSorted = [], statSorted = {};
        statColumns.forEach((statObj, i) => {
            statSorted = {};
            Object.keys(statObj).sort().forEach(key => {
                statSorted['N' + key] = statObj[key];
            });
            statColumnsSorted[i] = statSorted;
        });
        statColumns = null;
        return { statAll: statAllSorted, statColumns: statColumnsSorted };
    }

    /**
     * 获取大乐透官方远程数据
     * @returns Array 
     * 数据结构
     * list = [ drawing1, drawing2, ...]
     * drawing = {lotteryDrawNum: "24023", lotteryDrawResult: "08 10 12 14 22 05 09",lotteryUnsortDrawresult: "12 14 08 10 22 05 09"}
     */
    fetchData() {
        return new Promise((resolve, reject) => {
            // const url = 'https://lottery.izishu.cn/api.php/dlt/history';
            const url = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=60&isVerify=1&pageNo=1&termLimits=60';
            axios.get(url).then(res => {
                console.log('【获取大乐透官方远程数据】成功', res);
                resolve((res['data'] ? res.data : res).value.list.map(row => {
                    // resolve((res['data'] ? res.data.data : res).map(row => {
                    const { lotteryDrawNum, lotteryDrawResult, lotteryDrawTime } = row;
                    return { lotteryDrawNum, lotteryDrawResult, lotteryDrawTime };
                }));
            }).catch(err => {
                console.log('【获取大乐透官方远程数据】网络错误', err);
                reject(err);
            })
        })
    }

    /**
     * 封装加载数据方法
     * @param {Boolean} isForce 是否强制刷新数据。默认 false。
     * @returns resolve({rows, isLocalCache})
     * @version 1.0.1
     */
    loadData(isForce = false) {
        return new Promise((resolve, reject) => {
            let isLocalCache = false;
            if (isForce || this.isExpire() || this.getDataSource().length === 0) {
                console.log('【loadData】重新加载大乐透数据。刷新时间:', this.getRefreshTime(true));
                this.fetchData().then(rows => {
                    console.log('【loadData】加载大乐透远程数据成功');
                    this.setRefreshTime();
                    this.setDataSource(rows);
                    isLocalCache = false;
                    resolve({
                        rows,
                        isLocalCache
                    });
                }).catch(err => {
                    console.log('【loadData】加载大乐透数据错误', err);
                    reject(err);
                });
            } else {
                console.log('【loadData】使用大乐透本地缓存数据。刷新时间:', this.getRefreshTime(true));
                isLocalCache = true;
                resolve({
                    rows: this.getDataSource(),
                    isLocalCache
                });
            }
        });
    }
}

export default DltDataModel;